import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from "@nestjs/common";
import { Prisma, PrismaClient } from "@prisma/client";

/**
 * 实例化 PrismaClient，并且在模块初始化时连接数据库，并在模块销毁时断开连接。
 */
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
    private readonly Logger = new Logger(PrismaService.name);
    // constructor(@Inject(WINSTON_LOGGER) private readonly dbLogger) {
    constructor() {
        super({
            // datasourceUrl: process.env.DATABASE_URL,
            // 根据运行环境对错误级别的日志进行处理。开发：控制台打印。生产：emit 触发事件，监听事件然后在日志文件中记录。
            // 发现 log 配置没有 { emit: "event", level: "error" }，$on 监听 error 也能触发。
            log:
                process.env.NODE_ENV === "production"
                    ? [{ emit: "event", level: "error" }]
                    : [
                          { emit: "stdout", level: "info" },
                          { emit: "stdout", level: "query" },
                          { emit: "stdout", level: "warn" },
                          { emit: "stdout", level: "error" }
                      ]
        });
    }

    async onModuleInit() {
        try {
            await this.$connect();
            this.logPrismaError();
        } catch (error) {
            this.Logger.error(`Failed to connect to the database: ${error}`);
            // console.error("Failed to connect to the database:", error);
            throw error;
        }
    }

    async onModuleDestroy() {
        try {
            await this.$disconnect();
        } catch (error) {
            this.Logger.error(`Failed to disconnect from the database: ${error}`);
            // console.error("Failed to disconnect from the database:", error);
        }
    }

    private logPrismaError() {
        (this as any).$on("error", (event: Prisma.LogEvent) => {
            this.Logger.error(event);
        });
    }
}
